package br.com.locasis.utilitarios;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.NumberFormat;
import java.util.Locale;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;

public class UtilString {
	
private static UtilString instance;
	
	private UtilString(){}
	
	public static UtilString getInstance(){
		if(instance == null){
			instance = new UtilString();
		}
		return instance;
	}
	
	public static String removeAll(char c, String s) {
        String resposta;
        StringBuffer buffer = new StringBuffer(s);
        int pos = 0;
        while (pos < buffer.length()) {
            if (buffer.charAt(pos) == c) {
                buffer.deleteCharAt(pos);
            } else {
                pos = pos + 1;
            }
        }
        resposta = buffer.toString();
        return resposta;
    }
	
	public static boolean isStringVazia(String string) {
        return string==null || string.trim().equals("");
    }
	
	public static String desmascaraCpf(String cpf) {
		cpf = UtilString.removeAll('.', cpf);
		cpf = UtilString.removeAll('-', cpf);
		return cpf;
	}
	
	public static String md5(String senha) {   
        String sen = "";   
        MessageDigest md = null;   
        try {   
            md = MessageDigest.getInstance("MD5");   
        } catch (NoSuchAlgorithmException e) {   
            e.printStackTrace();   
        }   
        BigInteger hash = new BigInteger(1, md.digest(senha.getBytes()));   
        sen = hash.toString(16);   
        return sen;   
    }
	
	public static String valorPorExtenso(double vlr) {
	    if (vlr == 0)
	       return("zero");
	 
	    long inteiro = (long)Math.abs(vlr); // parte inteira do valor
	    double resto = vlr - inteiro;       // parte fracionária do valor
	 
	    String vlrS = String.valueOf(inteiro);
	    if (vlrS.length() > 15)
	       return("Erro: valor superior a 999 trilhões.");
	 
	    String s = "", saux, vlrP;
	    String centavos = String.valueOf((int)Math.round(resto * 100));
	 
	    String[] unidade = {"", "um", "dois", "três", "quatro", "cinco",
	             "seis", "sete", "oito", "nove", "dez", "onze",
	             "doze", "treze", "quatorze", "quinze", "dezesseis",
	             "dezessete", "dezoito", "dezenove"};
	    String[] centena = {"", "cento", "duzentos", "trezentos",
	             "quatrocentos", "quinhentos", "seiscentos",
	             "setecentos", "oitocentos", "novecentos"};
	    String[] dezena = {"", "", "vinte", "trinta", "quarenta", "cinquenta",
	             "sessenta", "setenta", "oitenta", "noventa"};
	    String[] qualificaS = {"", "mil", "milhão", "bilhão", "trilhão"};
	    String[] qualificaP = {"", "mil", "milhões", "bilhões", "trilhões"};
	 
	// definindo o extenso da parte inteira do valor
	    int n, unid, dez, cent, tam, i = 0;
	    boolean umReal = false, tem = false;
	    while (!vlrS.equals("0")) {
	      tam = vlrS.length();
	// retira do valor a 1a. parte, 2a. parte, por exemplo, para 123456789:
	// 1a. parte = 789 (centena)
	// 2a. parte = 456 (mil)
	// 3a. parte = 123 (milhões)
	      if (tam > 3) {
	         vlrP = vlrS.substring(tam-3, tam);
	         vlrS = vlrS.substring(0, tam-3);
	      }
	      else { // última parte do valor
	        vlrP = vlrS;
	        vlrS = "0";
	      }
	      if (!vlrP.equals("000")) {
	         saux = "";
	         if (vlrP.equals("100"))
	            saux = "cem";
	         else {
	           n = Integer.parseInt(vlrP, 10);  // para n = 371, tem-se:
	           cent = n / 100;                  // cent = 3 (centena trezentos)
	           dez = (n % 100) / 10;            // dez  = 7 (dezena setenta)
	           unid = (n % 100) % 10;           // unid = 1 (unidade um)
	           if (cent != 0)
	              saux = centena[cent];
	           if ((n % 100) <= 19) {
	              if (saux.length() != 0)
	                 saux = saux + " e " + unidade[n % 100];
	              else saux = unidade[n % 100];
	           }
	           else {
	              if (saux.length() != 0)
	                 saux = saux + " e " + dezena[dez];
	              else saux = dezena[dez];
	              if (unid != 0) {
	                 if (saux.length() != 0)
	                    saux = saux + " e " + unidade[unid];
	                 else saux = unidade[unid];
	              }
	           }
	         }
	         if (vlrP.equals("1") || vlrP.equals("001")) {
	            if (i == 0) // 1a. parte do valor (um real)
	               umReal = true;
	            else saux = saux + " " + qualificaS[i];
	         }
	         else if (i != 0)
	                 saux = saux + " " + qualificaP[i];
	         if (s.length() != 0)
	            s = saux + " " + s;
	         else s = saux;
	      }
	      if (((i == 0) || (i == 1)) && s.length() != 0)
	         tem = true; // tem centena ou mil no valor
	      i = i + 1; // próximo qualificador: 1- mil, 2- milhão, 3- bilhão, ...
	    }
	 
	    if (s.length() != 0) {
	       if (umReal)
	          s = s + " real";
	       else if (tem)
	               s = s + " reais";
	            else s = s + " de reais";
	    }
	 
	// definindo o extenso dos centavos do valor
	    if (!centavos.equals("0")) { // valor com centavos
	       if (s.length() != 0) // se não é valor somente com centavos
	          s = s + " e ";
	       if (centavos.equals("1"))
	          s = s + "um centavo";
	       else {
	         n = Integer.parseInt(centavos, 10);
	         if (n <= 19)
	            s = s + unidade[n];
	         else {             // para n = 37, tem-se:
	           unid = n % 10;   // unid = 37 % 10 = 7 (unidade sete)
	           dez = n / 10;    // dez  = 37 / 10 = 3 (dezena trinta)
	           s = s + dezena[dez];
	           if (unid != 0)
	              s = s + " e " + unidade[unid];
	         }
	         s = s + " centavos";
	       }
	    }
	    return(s);
	  }
	
	
	/*
     * realiza a formatacao do valor de acordo com a mascara enviada
     */
    public static String formatar( String valor, String mascara ) {
    
        String dado = "";      
        // remove caracteres nao numericos
        for ( int i = 0; i < valor.length(); i++ )  {
            char c = valor.charAt(i);
            if ( Character.isDigit( c ) ) { dado += c; }
        }

        int indMascara = mascara.length();
        int indCampo = dado.length();

        for ( ; indCampo > 0 && indMascara > 0; ) {
            if ( mascara.charAt( --indMascara ) == '#' ) { indCampo--; }
        }

        String saida = "";
        for ( ; indMascara < mascara.length(); indMascara++ ) {    
            saida += ( ( mascara.charAt( indMascara ) == '#' ) ? dado.charAt( indCampo++ ) : mascara.charAt( indMascara ) );
        }    
        return saida;
    }

	@SuppressWarnings("static-access")
	public String formatarCNPJ(String string) {
		return this.formatar(string, "##.###.###/####-##");
	}
	
	@SuppressWarnings("static-access")
	public String formatarContrato(String numContrato) {
		return this.formatar(this.concantenaEsquerda(numContrato, 9, '0'), "###.###.###");
	}

	@SuppressWarnings("static-access")
	public String formatarCPF(String string) {
		return this.formatar(string, "###.###.###-##");
	}
	
	@SuppressWarnings("static-access")
	public String formatarMoeda(String string) {
		return this.formatar(string,"R$ ###.###.##0,00");
	}
	
	public static String formatarMoeda(Float vlr) {
//		java.text.DecimalFormat df = new java.text.DecimalFormat("R$ ###,###,##0.00");
//		return df.format(vlr);
		Locale loc = new Locale("pt", "BR");
	    NumberFormat nf = NumberFormat.getCurrencyInstance(loc);
	    return nf.format(vlr);
	}
	
	@SuppressWarnings("static-access")
	public String formatarValor(String valor, String mascara ){
	    if(valor.length() == 1){
	        valor = this.concantenaEsquerda(valor, 3, '0');
	    }
	    if(valor.length() == 2){
	        valor = this.concantenaEsquerda(valor, 3, '0');
        }
	    return this.formatar(valor, mascara);
	}
	
	static public String formatarCep(String texto) {
		return formatar(texto, "##.###-###");
	}
	
	static public String formatarPlaca(String texto) {
		StringBuffer sb = new StringBuffer(texto);
		Pattern p = Pattern.compile("[a-zA-Z]{3}[0-9]{4}");  
	    if (p.matcher(texto).matches()) {
	    	return sb.insert(3, "-").toString().toUpperCase();
	    }
	    return "";
	}
	
	/**
	 * Concatena uma String � esquerda com um caractere espec�fico
	 * Ex:
	 * .concantenaEsquerda(null, *, *)     = null
	 * .concantenaEsquerda("", 3, 'z')     = "zzz"
	 * .concantenaEsquerda("bat", 3, 'z')  = "bat"
	 * .concantenaEsquerda("bat", 5, 'z')  = "zzbat"
	 * .concantenaEsquerda("bat", 1, 'z')  = "bat"
	 * .concantenaEsquerda("bat", -1, 'z') = "bat"
	 * @param str
	 * @param tamanho
	 * @param caractere
	 * @return
	 */
	public String concantenaEsquerda(String str, int tamanho, char caractere){
		return StringUtils.leftPad(str, tamanho, caractere);
	}
	
	/**
	 * Concatena uma String � direita com uma caractere especifico
	 * Ex:
	 * .concatenaDireita(null, *, *)     = null
	 * .concatenaDireita("", 3, 'z')     = "zzz"
	 * .concatenaDireita("bat", 3, 'z')  = "bat"
	 * .concatenaDireita("bat", 5, 'z')  = "batzz"
	 * .concatenaDireita("bat", 1, 'z')  = "bat"
	 * .concatenaDireita("bat", -1, 'z') = "bat"
	 * @param str
	 * @param tamanho
	 * @param caractere
	 * @return
	 */
	public String concatenaDireita(String str, int tamanho, char caractere){
		return StringUtils.rightPad(str, tamanho, caractere);
	}
	
	public boolean isVazia(final String str) {
		return StringUtils.isEmpty(str.trim());
	}
	
	public boolean isNaoVazia(final String str) {
		return StringUtils.isNotEmpty(str.trim());
	}
	
	public boolean isMenor(final int tam, final String str) {
		return StringUtils.length(str.trim()) < tam;
	}
	
	public boolean isNulo(final String str) {
		return str == null;
	}
	
	public boolean isNaoNulo(final String str) {
		return str != null;
	}
	
	public boolean isNaoNuloNaoVazio(final String str) {
		return str != null && StringUtils.isNotEmpty(str.trim());
	}
	
	public boolean isNaoNuloVazio(final String str) {
		return str != null && StringUtils.isEmpty(str.trim()); 
	}

}
